﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;

namespace OwElectrePromethee
{
    public class EKryterium
    {
        public EKryterium(int id, double waga, double q, double p, double v, string name, EKryteriumTyp typ)
        {
            Id = id;
            Waga = waga;
            Q = q;
            P = p;
            V = v;
            Name = name;
            Typ = typ;
        }

        public EKryterium() { }

        [Description("Nazwa")]
        public string Name { get; set; }

        [Description("Id kryterium")]
        public int Id { get; set; }

        [Description("Waga")]
        public double Waga { get; set; }

        [Description("Próg nierozróżnialności")]
        public double Q { get; set; }

        [Description("Próg silnej preferencji")]
        public double P { get; set; }

        [Description("Veto")]
        public double V { get; set; }

        [Description("Typ kryterium")]
        public EKryteriumTyp Typ { get; set; }

        public double getCi(double w1Value, double w2Value)
        {
            using (TextWriter writer = new StreamWriter("getCi.txt", true))
            {
                writer.Write("w1value:{0}, w2value:{1}, ", w1Value, w2Value);
                if (this.Typ == EKryteriumTyp.Koszt)
                {
                    double diff = w1Value - w2Value;
                    writer.Write("diff:{0} ", diff);

                    if (diff < 0) //w1 jest tańszy (lepszy) od w2 //czyli na pewno Xy
                    {
                        writer.WriteLine("ret:1");
                        return 1;
                    }
                    else
                    {
                        if (diff < Q)
                        {
                            writer.WriteLine("ret:1");
                            return 1;
                        }
                        else if (diff < P) //v1 > v2, bo v1 - v2 > 0
                        {
                            double szerokoscPrzedzialuQ2P = P - Q;
                            double diffNormalized = diff - Q;
                            double ret = (szerokoscPrzedzialuQ2P - diffNormalized) / szerokoscPrzedzialuQ2P;

                            writer.WriteLine("P:{0} Q:{1} szP:{2} diffN:{3} ret:{4}", P, Q, szerokoscPrzedzialuQ2P, diffNormalized, ret);
                            return ret;
                        }
                        else
                        {
                            writer.WriteLine("ret:0");
                            return 0;
                        }
                    }
                }
                else if (this.Typ == EKryteriumTyp.Zysk)
                {
                    double diff = w1Value - w2Value;
                    writer.Write("diff:{0} ", diff);

                    if (diff < 0) //w1 jest mniej warty (gorszy) od w2 //czyli na pewno Yx
                    {
                        if (diff > -Q)
                        {
                            writer.WriteLine("ret:1");
                            return 1;
                        }
                        else if (diff > -P)
                        {
                            double szerokoscPrzedzialuQ2P = P - Q;
                            double diffNormalized = -diff - Q;//należy liczyć z drugiego końca przedziału niż przy koszcie
                            double ret = (szerokoscPrzedzialuQ2P - diffNormalized) / szerokoscPrzedzialuQ2P;

                            writer.WriteLine("P:{0} Q:{1} szP:{2} diffN:{3} ret:{4} -", P, Q, szerokoscPrzedzialuQ2P, diffNormalized, ret);
                            return ret;
                        }
                        else
                        {
                            writer.WriteLine("ret:0");
                            return 0;
                        }
                    }
                    else
                    {
                        writer.WriteLine("ret:1");
                        return 1;
                    }
                }

                writer.WriteLine("ret:0");
                return 0;
            }
        }

        public ERelacje Compare(double w1Value, double w2Value)
        {
            if (this.Typ == EKryteriumTyp.Koszt)
            {
                double diff = w1Value - w2Value;

                if (diff < 0) //w1 jest tańszy (lepszy) od w2 //czyli na pewno Xy
                {
                    if (diff > -Q) return ERelacje.Nierozroznialne;
                    else if (diff > -P) return ERelacje.SlabaPreferencjaW_P;
                    else return ERelacje.SilnaPreferencjaW_P;
                }
                else
                {
                    if (diff < Q) return ERelacje.Nierozroznialne;
                    else if (diff < P) return ERelacje.SlabaPreferencjaP_W;
                    else return ERelacje.SilnaPreferencjaP_W;
                }
            }
            else if (this.Typ == EKryteriumTyp.Zysk)
            {
                double diff = w1Value - w2Value;

                if (diff < 0) //w1 jest mniej warty (gorszy) od w2 //czyli na pewno Yx
                {
                    if (diff > -Q) return ERelacje.Nierozroznialne;
                    else if (diff > -P) return ERelacje.SlabaPreferencjaP_W;
                    else return ERelacje.SilnaPreferencjaP_W;
                }
                else
                {
                    if (diff < Q) return ERelacje.Nierozroznialne;
                    else if (diff < P) return ERelacje.SlabaPreferencjaW_P;
                    else return ERelacje.SilnaPreferencjaW_P;
                }
            }


            return ERelacje.Nieporownywalne;
        }

        public override string ToString()
        {
            return String.Format("{0}:{1}, Q:{2}, P:{3}, V:{4}, Waga:{5}, {6}", Id, Name, Q, P, V, Waga, Typ);
        }
    }

    public class EKryteriaList
    {
        public EKryteriaList()
        {
            this.List = new List<EKryterium>();
        }

        public List<EKryterium> List { get; set; }
    }

    public enum EKryteriumTyp { Koszt = 1, Zysk = 2 }
}

